Overview

Cross-Site Request Forgery (CSRF) is a type of attack used to trick the victim into sending a malicious request. It utilises the identity and privileges of the target in order to perform an undesired action on the victim's behalf. It is similar to indirect impersonation - you can make the victim's browser submit requests as the victim. It is called "cross-site" because a malicious website can make the victim's browser send a request to another website.

This attack typically relies on the victim being authenticated - either through cookies or basic header authorization.

How does it work

There are two primary types of CSRF - through GET requests and through POST requests (although methods like PUT and DELETE may also be exploitable).

When your browser submits a request to a web server, it also sends along all stored cookies. If CSRF occurs, any authentication cookies will be sent with the request and as such, any actions on the server would be performed on the victim's behalf. Note that in order for CSRF to work, the victim needs to be logged in because when you make a log out request, the web server usually returns an HTTP response which auto-expires your authentication cookies and they are no longer valid.

In order for it to work, the victim would need to visit your malicious website.

The GET scenario

This typically relies on hidden images through the HTML <img> tag. This tag takes an src attribute which will tell the victim's browser to perform a GET request to the specified URL in order to retrieve an image. However, an attacker can change this URL and even add parameters to it, so that the browser performs a GET request to any arbitrary site.

An example of such a malicious hidden image could be this:

<img src="http://bank.com/transfer?recipient=John&amount=1000" width="0" height="0" border="0">

When visiting your malicious site, this will make the victim's browser submit a GET request. Any cookies stored for bank.com would be sent along, including any authentication ones. As such, the bank would complete the transfer from the victim's account.

The POST scenario

If the bank uses POST requests for transfers, the <img> method won't work because image tags can't initiate POST requests. This can however be achieved through hidden forms.

<iframe style="display:none" name="csrf-frame"></iframe>  
<form method='POST' action='http://bank.com/transfer' target="csrf-frame"  
id="csrf-form">  
	<input type='hidden' name='recipient' value='John'>  
	<input type='hidden' name='amount' value='1000'>  
	<input type='submit' value='submit'>  
</form>  
<script>document.getElementById("csrf-form").submit()</script>

Normally, the submition of the form will require that a user clicks the submit button, but this can be automated through Javascript. The response from the submission of the POST request would be redirect to the non-displayed iframe and so the victim would never see what has happened.

Preventions

CSRF Tokens

Sometimes, websites will make use of two-part tokens called CSRF tokens in order to prevent cross-site request forgery. These tokens are generated on the server - one part is sent to the user and the other is kept private. This value is submitted with the request and validated on the server. If the CSRF token isn't correct, the server shouldn't fulfill the submission.

These tokens may be part of the POST request's body or as custom HTTP headers. They may take on any name, but some common ones include CSRF, CSRFToken, X-CSRF-TOKEN, form-id, lt, lia-token, etc.

You should always try removing or altering the CSRF token in order to check if it's properly implemented.

CORS

When a browser sends an
application/json POST request to a site, it will send an OPTIONS request beforehand. The site then returns a
response indicating which types of HTTP
requests the server accepts and from what trusted origins. Such OPTIONS requests are called preflight OPTIONS requests.

CORS, or Cross-Origin Resource Sharing, restricts resource access, including JSON response access, from domains outside the one which served a file is allowed by the site being tested. When CORS is used, submitting application/json requests are not possible, unless the website explicitly allows them.

These protections can sometimes be bypassed by changing the content-type header to application/x- www-form-urlencoded, multipart/form-data, or text/plain. Browsers don't send preflight OPTIONS requests for any of these content types and CSRF requests might succeed.

Origin and Referer Headers

Checking the Origin and Referer headers (if the origin header isn't present) prevents CSRF because these headers are controlled by the browsers and cannot be altered by the attacker

This attribute can take on the values strict or lax. When set to strict, the browser won't send that specific cookie with any request that doesn't originate from the correct website - including GET requests.

Setting the attribute to lax will prevent the cookie from being sent on normal subrequests (such as loading images or frames), however, the cookie will still be sent with direct requests to the origin site (such as those initiated by clicking on a link).